#include "dictlist.h"

DictList::DictList( DbLink* pcDbLink, wxString& soundFileDir )
: DictDialog( NULL ), BaseList( m_listCtrl, soundFileDir )
{	
	m_pcDbLink = pcDbLink;
	m_pDictDb  = pcDbLink->GetDictDb();
	m_pCardDb  = pcDbLink->GetCardDb();

	m_lItemIdx = -1;
	m_iDictNum = -1;
		
	m_listCtrl->InsertColumn( eDict_PrimLang,  _("Primary language"),     wxLIST_FORMAT_LEFT, 170 );
	m_listCtrl->InsertColumn( eDict_TranLang,  _("Translation language"), wxLIST_FORMAT_LEFT, 170 );
	m_listCtrl->InsertColumn( eDict_Name,      _("Dictionary name"),      wxLIST_FORMAT_LEFT, 170 );
	m_listCtrl->InsertColumn( eDict_TableName, _("Table name"),           wxLIST_FORMAT_LEFT, 0 );
	m_listCtrl->InsertColumn( eDict_Words,     _("Words"),                wxLIST_FORMAT_LEFT, 70);
	
	m_buttonOk->SetFocus();
}

DictList::~DictList()
{
}

void DictList::OnEnterWindow( wxMouseEvent& event )
{
	m_listCtrl->SetFocus();
}

void DictList::OnOkClick( wxCommandEvent& event )
{
	wxString sPrimLang = GetPrimLang();
	wxString sTranLang = GetTranLang();
	wxString sDictName = GetDictName();
		
	if( ( sPrimLang.empty() && sTranLang.empty() && sTranLang.empty() ) || ( sPrimLang == m_sPrimLang && sTranLang == m_sTranLang && sDictName == m_sDictName ) )
	{
		if( IsModal() )
			EndModal( wxID_OK );
		return;
	}
	
	// create db
	if( m_sPrimLang.empty() && m_sTranLang.empty() && m_sDictName.empty() )
	{
		OnCreateClick( event );
		return;		
	}
		
	// update db entry
	if( ( sPrimLang != m_sPrimLang && sPrimLang.length() && m_sPrimLang.length() ) || 
	    ( sTranLang != m_sTranLang && sTranLang.length() && m_sTranLang.length() ) || 
			( sDictName != m_sDictName && sDictName.length() && m_sDictName.length() ) )
	{		
		wxString sQuery = wxT( "UPDATE " ) + m_sTableName + 
			wxT( " SET word = '") + sDictName + wxT("', tran = '") + sPrimLang + wxT(";") + sTranLang + wxT("' WHERE id = 1");
				
		m_pDictDb->ExecuteUpdate( sQuery );
		
		// uodate item text in the list
		UpdateItem();
	}
	else
		wxMessageDialog( NULL, wxT("Nothing to update"), wxT("Info"), wxOK | wxICON_INFORMATION ).ShowModal();
}
	
void DictList::OnLeftDClick( wxMouseEvent& event ) 
{ 
	if( m_bToggle )
		OnOkClick( (wxCommandEvent&) event );
	else
		OnOpenClick( (wxCommandEvent&) event ); 
}
	
void DictList::OnCancelClick( wxCommandEvent& WXUNUSED( event ) )
{
	if( IsModal() )
		EndModal( wxID_CANCEL );
}

void DictList::OnOpenClick( wxCommandEvent& WXUNUSED( event ) )
{
	if( m_lItemIdx < 0 || m_sTableName.IsEmpty() )
		return;
		
	WordList cWordList( m_sTableName, m_pDictDb, m_pCardDb, m_sSoundDir );
	cWordList.Load();
	cWordList.ShowModal();
	
	m_listCtrl->SetItem( m_lItemIdx, eDict_Words, wxString::Format( wxT("%i"), cWordList.GetWordsNum() ) );
}

void DictList::ClearText()
{
	wxString s = _("");
	SetPrimLang( s );
	SetTranLang( s );
	SetDictName( s );
}

void DictList::OnDeleteClick( wxCommandEvent& WXUNUSED( event ) )
{
	if( m_lItemIdx < 0 || m_sTableName.empty() )
		return;
	
	// get last dict from db
	wxSQLite3ResultSet cResultSet = m_pDictDb->ExecuteQuery( "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name DESC LIMIT 1" );
	wxString sLastTableName = cResultSet.GetAsString(0);
	cResultSet.Finalize();
	
	// delete table from db
	m_pDictDb->ExecuteUpdate( wxT( "DROP TABLE " ) + m_sTableName );
	
	m_iDictNum--;
	
	// delete sound file dir
	wxString dir = m_sSoundDir + wxT("/") + m_sTableName;
	if( !wxRmdir( dir ) )
	{
		// force to delete, platform dependent
		wxString command = wxT("rm -R \"");
		command += dir + wxT("\"");
		int res = std::system( command.mb_str() );
	}
	
	if( sLastTableName != m_sTableName )
	{
		// update table names
		m_pDictDb->ExecuteUpdate( wxT("ALTER TABLE ") + sLastTableName + wxT(" RENAME TO ") + m_sTableName );
			
		// update dir name
		wxString sLastDir = m_sSoundDir + wxT("/") + sLastTableName;
		wxRename( sLastDir, dir );
	}
	
	// update cards
	cResultSet = m_pCardDb->ExecuteQuery( wxT( "SELECT name FROM sqlite_master T WHERE type='table' AND T.name != 'cards'" ) );

	while( cResultSet.NextRow() )
	{			
		wxString sTableName = cResultSet.GetAsString(0);
		
		m_pCardDb->ExecuteUpdate( wxT( "DELETE FROM ") + sTableName + wxT(" WHERE dicttable = '" ) + m_sTableName + wxT("'") );
		
		if( sLastTableName != m_sTableName )
			m_pCardDb->ExecuteQuery( wxT( "UPDATE ") + sTableName + wxT(" SET dicttable = '" ) + m_sTableName + wxT("' WHERE dicttable ='") + sLastTableName + wxT("'") );
	}
	
	cResultSet.Finalize();
	
	// request new card and word seta due to dictionaty removal
	m_pcDbLink->FinalizeSets();
	
	m_iDictNum = FillDictList( true );
}

void DictList::OnDictSelected( wxListEvent& WXUNUSED( event ) )
{	
	m_lItemIdx = -1;
	m_lItemIdx = m_listCtrl->GetNextItem( m_lItemIdx, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED );

	m_sTableName.clear();
		
	if( m_lItemIdx >= 0 )
	{			
		m_sTableName = GetColumnText( eDict_TableName );
		m_buttonDelete->Enable( true );
		m_buttonOpen->Enable( true );
		
		m_sPrimLang = GetColumnText( eDict_PrimLang );
		SetPrimLang( m_sPrimLang );
		
		m_sTranLang = GetColumnText( eDict_TranLang );
		SetTranLang( m_sTranLang );
			
		m_sDictName = GetColumnText( eDict_Name );
		SetDictName( m_sDictName );
	}
}

void DictList::OnDictDeselected( wxListEvent& WXUNUSED( event ) )
{	
	m_buttonDelete->Enable( false );
	m_buttonOpen->Enable( false );
	ClearText();
	ClearInfo();
}

long DictList::FillDictList( bool bClear )
{
	// clear list
	if( bClear )
	{
		ClearText();
		ClearInfo();		
		m_pcListCtrl->DeleteAllItems();		
	}
		
	// get list of tables in the db
	wxSQLite3ResultSet cDictSet = m_pDictDb->ExecuteQuery( wxT( "SELECT name FROM sqlite_master WHERE type='table'" ) );
	long iCount = 0;
	
	// fill the dict list
	while( cDictSet.NextRow() )
	{			
		wxString sTable = cDictSet.GetAsString(0);
		
		// get number of words in the dict
		wxString sQuery = wxT( "SELECT count(*) FROM " )  + sTable + wxT( " WHERE id > 1" );
		wxSQLite3ResultSet cResultSet = m_pDictDb->ExecuteQuery( sQuery );
		wxString sWords = cResultSet.GetAsString(0);
		
		// get dict info
		sQuery = wxT( "SELECT word, tran FROM " ) + sTable + wxT( " WHERE id = 1" );
		cResultSet = m_pDictDb->ExecuteQuery( sQuery );
		
		wxString s[eDict_Cols];
		
		s[eDict_Name] =  cResultSet.GetAsString(0);
		s[eDict_PrimLang] = cResultSet.GetAsString(1);
		s[eDict_TranLang] = s[eDict_PrimLang].AfterLast(';');
		s[eDict_PrimLang] = s[eDict_PrimLang].BeforeLast(';');
		s[eDict_Words] = sWords;
		s[eDict_TableName] = sTable;
		
		InsertItem( s, eDict_Cols );
		
		cResultSet.Finalize();
		
		iCount++;
	}
	cDictSet.Finalize();
	
	return iCount;
}

void DictList::OnCreateClick( wxCommandEvent& WXUNUSED( event ) )
{
	// try do add new db entry
	if( GetPrimLang().empty() )
	{
		m_textCtrlPrimLang->SetFocus();
	}
	else if( GetTranLang().empty() )
	{
		m_textCtrlTranLang->SetFocus();
	}
	else if( GetDictName().empty() )
	{
		m_textCtrlDictName->SetFocus();
	}
	else
	{
		m_sTableName = wxT( "dict" );
		m_sTableName << m_iDictNum;
			
		wxString sQuery = wxT( "CREATE TABLE " ) + m_sTableName + 
			wxT( "( id INTEGER PRIMARY KEY, word VARCHAR(100), tran VARCHAR(200) )" );
			
		m_pDictDb->ExecuteUpdate( sQuery );
		
		sQuery = wxT( "INSERT INTO " ) + m_sTableName + 
			wxT( " VALUES (NULL, '") + GetDictName() + wxT("', '") + GetPrimLang() + wxT(";") + GetTranLang() + wxT("')");
		
		m_pDictDb->ExecuteUpdate( sQuery );
						
		wxString s[eDict_Cols];
		s[eDict_PrimLang]  = GetPrimLang();
		s[eDict_TranLang]  = GetTranLang();
		s[eDict_Name]      = GetDictName();
		s[eDict_Words]     = wxT("0");
		s[eDict_TableName] = m_sTableName;

		InsertItem( s, eDict_Cols );
		
		ClearText();
		
		m_iDictNum++;
		
		// create sound file dir
		wxMkdir( m_sSoundDir + wxT("/") + m_sTableName );
	}	
}

void DictList::Load()
{
	m_iDictNum = FillDictList();
}

void DictList::UpdateItem()
{
	if( m_lItemIdx < 0 )
		return;
		
	m_sPrimLang = GetPrimLang();
	m_sTranLang = GetTranLang();
	m_sDictName = GetDictName();
	
	m_pcListCtrl->SetItem( m_lItemIdx, eDict_PrimLang, m_sPrimLang );
	m_pcListCtrl->SetItem( m_lItemIdx, eDict_TranLang, m_sTranLang );
	m_pcListCtrl->SetItem( m_lItemIdx, eDict_Name,      m_sDictName );
}

void DictList::DirsUpdate( long iNum )
{
	long iCount = 0;
	
	wxString dir = wxFindFirstFile( m_sSoundDir + wxT("/*"), wxDIR );
	
  while ( !dir.empty() )
  {
		long idx = TableToLong( dir );
		
		if( idx > iNum )
		{
			wxString sNewDir = wxT("dict");
			sNewDir << ( idx - 1 );
			wxRename( dir, sNewDir );
		}
			
		iCount++;
		dir = wxFindNextFile();
  }
}

void DictList::ClearInfo()
{
	m_sPrimLang.clear();
	m_sTranLang.clear();
	m_sDictName.clear();
	m_sTableName.clear();
}

void DictList::OnKeyDown( wxKeyEvent& event )
{
	if( event.GetKeyCode() == WXK_ESCAPE )
		OnCancelClick( (wxCommandEvent&) event );
	else
		event.Skip();
}